package com.website.core.listener;

import com.website.common.controller.BaseController;
import com.website.common.exception.InvalidSessionException;
import com.website.common.exception.IsLoginValidException;
import com.website.common.exception.UrlErrorException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;

import java.lang.reflect.Method;

/**
 * 拦截注解@requestMapping，判断用户是否登录
 *
 * @author fengshuonan
 * @date 2016年11月13日 下午10:15:42
 */
@Aspect
@Component
public class RequestMappingInterceptor extends BaseController {

    //    @Pointcut("execution(* com.website.system.controller.*.*(..))")
    @Aspect
    @Component
    public class MethodTime {
        Logger logger = LoggerFactory.getLogger(MethodTime.class);
        //开始时间
        private long starttime;

        //声明切入点的访问路径
        @Pointcut("execution(* com.website.system.controller.PharmacyController.*(..))")
        public void point() {

        }

        /**
         * 前置通知（Before advice） ：在某连接点（JoinPoint）之前执行的通知，但这个通知不能阻止连接点前的执行。
         *
         * @param joinPoint
         */
        @Before("point()")
        public void doBefore(JoinPoint joinPoint) {
            System.out.println("=====SysLogAspect前置通知开始=====");
            //handleLog(joinPoint, null);
        }

        @Around("point()")
        public Object doAround(ProceedingJoinPoint joinPoint) {
            long starttime = System.currentTimeMillis();
            Object obj = null;
            try {
                obj = joinPoint.proceed();
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
            long endtime = System.currentTimeMillis();
            Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
            String methodName = method.getName();
            logger.info(methodName + "方法执行了" + (endtime - starttime) + "ms");
            return obj;
        }

        /**
         * 后通知（After advice） ：当某连接点退出的时候执行的通知（不论是正常返回还是异常退出）。
         *
         * @param joinPoint
         */
        @AfterReturning(pointcut = "point()")
        public void doAfter(JoinPoint joinPoint) {
            System.out.println("=====SysLogAspect后置通知开始=====");
            //handleLog(joinPoint, null);
        }

    }

    @Around("@annotation(requestMapping)")
    public Object bindUserAdvice(ProceedingJoinPoint pjp, RequestMapping requestMapping) throws Throwable {

        Method method = ((MethodSignature) pjp.getSignature()).getMethod();
        String methodName = method.getName();

        // 网页page请求直接通过，错误页面属于路径请求有误，未登录其他访问
        if (methodName.contains("page")) {
            return pjp.proceed();
        }
        //直接通过sendMessage请求
        if (methodName.contains("SendEmail") || methodName.contains("SendEmail")) {
            return pjp.proceed();
        }
        //直接通过sendMessage请求
        if (methodName.contains("sendMessage") || methodName.contains("SendMessage")) {
            return pjp.proceed();
        }
        // 网页registerUser请求直接通过，错误页面属于路径请求有误，未登录其他访问
        if (methodName.contains("register") || methodName.contains("Register")) {
            return pjp.proceed();
        }
        // 网页registerUser请求直接通过，错误页面属于路径请求有误，未登录其他访问
        if (methodName.contains("AddDrug") || methodName.contains("AddDrug")) {
            return pjp.proceed();
        }
        // 网页registerUser请求直接通过，错误页面属于路径请求有误，未登录其他访问
        if (methodName.contains("AddUrl") || methodName.contains("AddUrl")) {
            return pjp.proceed();
        }

        if ("errorHtml".equals(methodName)) {
            throw new UrlErrorException();
        }

        if (getSession(false) == null) {
            removeUser();
            throw new InvalidSessionException();
        }

        if (!"login".equals(methodName) && !"error".equals(methodName)
                && !"loginValid".equals(methodName) && !"kaptcha".equals(methodName)) {
            if (getCurrentUser() == null) {
                throw new IsLoginValidException();
            }
        }

        return pjp.proceed();
    }
}
